///////////////////////////////////////////////////////////////////////////////
// File:        Logger.cc
// Author:      671643387@qq.com
// Description:
///////////////////////////////////////////////////////////////////////////////

#include <cassert>
#include <cstdarg>
#include "common/Config.hpp"
#include "common/TimeUtil.hpp"
#include "common/Logger.hpp"
using namespace monkey::common;

#if defined(__WINDOWS__)
#pragma warning(disable:4996)
#endif

///////////////////////////////////////////////////////////////////////////////

static void WriteLog(FILE* fp, const char* fmt, std::va_list arg)
{
#if defined(__DEBUG__)
    char buf[0x10000];
    vsprintf(buf, fmt, arg);
    fprintf(stdout, buf);
    fprintf(fp, buf);
#else
    vfprintf(fp, fmt, arg);
#endif
}

///////////////////////////////////////////////////////////////////////////////

Logger::Logger(std::string norFile, std::string errFile)
    : level_(LOGLV_LOG)
    , norFile_(fopen((LOGGER_LOG_PATH + norFile).c_str(), "a+"))
    , errFile_(fopen((LOGGER_LOG_PATH + errFile).c_str(), "a+"))
{
    assert(norFile_ && errFile_);
}

Logger::~Logger()
{
    if (norFile_)
        fclose(norFile_);
    if (errFile_)
        fclose(errFile_);
}

void Logger::Log(const char* format, ...)
{
    if ((int)level_ < (int)LOGLV_LOG)
        return;

    std::va_list varg;
    va_start(varg, format);
    WriteLog(norFile_, format, varg);
    va_end(varg);
    fflush(norFile_);
}

void Logger::Warning(const char* format, ...)
{
    if ((int)level_ < (int)LOGLV_WARNING)
        return;

    std::va_list varg;
    va_start(varg, format);
    WriteLog(norFile_, format, varg);
    va_end(varg);
    fflush(norFile_);
}

void Logger::Error(const char* format, ...)
{
    if ((int)level_ < (int)LOGLV_ERROR)
        return;

    std::va_list varg;
    va_start(varg, format);
    WriteLog(errFile_, format, varg);
    va_end(varg);
    fflush(errFile_);
}

void Logger::Log(const char* mod, const char* format, ...)
{
    char buf[256];
    sprintf(buf, "%ld, [%s], [N], %s\n", TimeUtil::fromStartup(), mod, format);

    std::va_list varg;
    va_start(varg, format);
    WriteLog(norFile_, buf, varg);
    va_end(varg);
    fflush(norFile_);
}

void Logger::Warning(const char* mod, const char* format, ...)
{
    char buf[256];
    sprintf(buf, "%ld, [%s], [W], %s\n", TimeUtil::fromStartup(), mod, format);

    std::va_list varg;
    va_start(varg, format);
    WriteLog(norFile_, buf, varg);
    va_end(varg);
    fflush(norFile_);
}

void Logger::Error(const char* mod, const char* format, ...)
{
    char buf[256];
    sprintf(buf, "%ld, [%s], [E], %s\n", TimeUtil::fromStartup(), mod, format);

    std::va_list varg;
    va_start(varg, format);
    WriteLog(errFile_, buf, varg);
    va_end(varg);
    fflush(norFile_);
}

void Logger::SetLevel(Logger::Level level)
{
    level_ = level;
}

Logger::Level Logger::GetLevel() const
{
    return level_;
}